package com.chj.zhongji.class01;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

// https://blog.csdn.net/weixin_44726516/article/details/111566659
// https://www.nowcoder.com/questionTerminal/ed610b2fea854791b7827e3111431056?toCommentId=4141697
// https://codeleading.com/article/61172121039/
public class Code05_MaxRectangle {
//	import java.io.BufferedReader;
//	import java.io.IOException;
//	import java.io.InputStreamReader;
//	import java.util.Stack;
//
//	public class Main {
	/**
	 * 时间复杂度O(N * M)
	 */
	public static int maxRecSize(int[][] map) {
		// 排除三种特例： null 空数组[] 空数组[[]]
		if (map == null || map.length < 1 || map[0].length < 1) {
			return -1;
		}
		int n = map.length;
		int m = map[0].length;
		int[] height = new int[m];
		int maxArea = 0;
		// 统计从第i行开始每列往上有多少个连续的1
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				height[j] = map[i][j] == 0 ? 0 : height[j] + 1;
			}
			maxArea = Math.max(maxRecFromBottom(height), maxArea);
		}
		return maxArea;
	}

	/**
	 * 相当于寻找height中每个元素左边和右边的第一个比它小的元素，时间复杂度O(M)
	 */
	private static int maxRecFromBottom(int[] height) {
		// 排除两种特例：null 空数组[]
		if (height == null || height.length < 1) {
			return -1;
		}
		// 单调栈初始化
		Stack<Integer> stack = new Stack<>();
		int i = 0;
		int cur;
		int rightLessIndex;
		int maxArea = 0;
		int curArea;
		while (i < height.length) {
			if (stack.isEmpty() || height[i] > height[stack.peek()]) {
				// 满足从栈顶到栈底单调递减时，压入
				stack.push(i);
				i++;
			} else {
				// 不满足栈顶到栈底单调递减时，淡出
				cur = stack.pop();
				rightLessIndex = stack.isEmpty() ? -1 : stack.peek();
				// 计算当前列及其左边最大子矩阵的大小
				curArea = (i - rightLessIndex - 1) * height[cur];
				maxArea = Math.max(curArea, maxArea);
			}
		}
		// 清算栈中剩余的元素，这些元素右边没有比它小的数字
		while (!stack.isEmpty()) {
			cur = stack.pop();
			rightLessIndex = stack.isEmpty() ? -1 : stack.peek();
			// 计算当前列及其左边最大子矩阵的大小
			curArea = (i - rightLessIndex - 1) * height[cur];
			maxArea = Math.max(curArea, maxArea);
		}
		return maxArea;
	}

	public static void main(String[] args) throws IOException {
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
		String[] numbers = bufferedReader.readLine().split(" ");
		int n = Integer.valueOf(numbers[0]);
		int m = Integer.valueOf(numbers[1]);
		int[][] map = new int[n][m];
		for (int i = 0; i < n; i++) {
			numbers = bufferedReader.readLine().split(" ");
			for (int j = 0; j < m; j++) {
				map[i][j] = Integer.parseInt(numbers[j]);
			}
		}
		System.out.println(maxRecSize(map));
	}
//	}
}
